package nmrworkflow.framework.executionmodule;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import nmrworkflow.framework.beans.datasets.NmrDataSet;
import nmrworkflow.framework.beans.datatypes.Streamable;
import nmrworkflow.framework.executionmodule.interfaces.DataProcessor;

public class StreamProcessor<I extends NmrDataSet<Streamable>, O extends NmrDataSet<Streamable>> implements DataProcessor<I, O>
{
	private Process process;
	private String[] cmdLine;
	final private Class inputType, outputType;
	private I input;
	private O output;
	
	public StreamProcessor(Class inputType, Class outputType, String[] cmdLine)
	{
		super();
		this.cmdLine = cmdLine;
		this.inputType = inputType;
		this.outputType = outputType;
	}
	
	public void run() throws IOException, InterruptedException
	{
		run(false);
	}
	
	public void run(boolean wait) throws IOException, InterruptedException
	{	
		Runtime r = Runtime.getRuntime();
		InputStream inputStream = input.getData().getInputStream();
		OutputStream outputStream = output.getData().getOutputStream();
		StreamAdapter inputStreamAdapter, outputStreamAdapter;
		Thread inputThread, outputThread;
		
		process = r.exec(cmdLine);
		
		inputStreamAdapter = new StreamAdapter(inputStream, process.getOutputStream());
		inputThread = new Thread(inputStreamAdapter);
		inputThread.run();
		
		outputStreamAdapter = new StreamAdapter(process.getInputStream(), outputStream);
		outputThread = new Thread(outputStreamAdapter);
		outputThread.run();
		
		if(wait)
			outputThread.wait();
		
	}
	
	public void setInput(I input)
	{
		this.input = input;
	}
	
	public void setOutput(O output)
	{
		this.output = output;
	}
	
	public I getInput()
	{
		return input;
	}
	
	public O getOutput()
	{
		return output;
	}
	
	public Class getInputType()
	{
		return inputType;
	}
	
	public Class getOutputType()
	{
		return outputType;
	}
}
